package com.kexio.file.service;

import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.kexio.file.entity.StorageObject;
import com.kexio.file.storage.StorageResult;
import com.kexio.file.vo.StorageObjectVO;

/**
 * 存储对象服务接口
 * 
 * 提供存储对象管理的核心业务逻辑，包括：
 * - 存储对象CRUD操作
 * - 引用计数管理
 * - 去重和复用
 * - 存储验证和维护
 * - 多租户数据隔离
 * 
 * @author Kexio Team
 * @since 1.0.0
 */
public interface StorageObjectService {
    
    // ==================== 存储对象创建 ====================
    
    /**
     * 创建或获取存储对象（支持去重）
     * 
     * @param inputStream 文件输入流
     * @param contentLength 内容长度
     * @param contentType 内容类型
     * @param storageType 存储类型（可选，默认使用配置）
     * @param bucketName 存储桶名称（可选，默认使用配置）
     * @param metadata 元数据
     * @return 存储对象
     */
    StorageObject createOrGetStorageObject(InputStream inputStream, long contentLength, 
                                          String contentType, String storageType, 
                                          String bucketName, Map<String, String> metadata);
    
    /**
     * 根据内容哈希查找或创建存储对象
     * 
     * @param contentHash 内容哈希值
     * @param inputStream 文件输入流（如果需要创建）
     * @param contentLength 内容长度
     * @param contentType 内容类型
     * @param storageType 存储类型
     * @param bucketName 存储桶名称
     * @param metadata 元数据
     * @return 存储对象
     */
    StorageObject findOrCreateByContentHash(String contentHash, InputStream inputStream, 
                                           long contentLength, String contentType, 
                                           String storageType, String bucketName, 
                                           Map<String, String> metadata);
    
    // ==================== 基础CRUD操作 ====================
    
    /**
     * 根据ID查询存储对象
     * 
     * @param storageObjectId 存储对象ID
     * @return 存储对象
     */
    StorageObject getById(String storageObjectId);
    
    /**
     * 根据ID查询存储对象VO
     * 
     * @param storageObjectId 存储对象ID
     * @return 存储对象VO
     */
    StorageObjectVO getVOById(String storageObjectId);
    
    /**
     * 根据内容哈希查询存储对象
     * 
     * @param contentHash 内容哈希值
     * @return 存储对象
     */
    StorageObject getByContentHash(String contentHash);
    
    /**
     * 更新存储对象信息
     * 
     * @param storageObjectId 存储对象ID
     * @param storageObject 更新的存储对象信息
     * @return 更新后的存储对象
     */
    StorageObject updateStorageObject(String storageObjectId, StorageObject storageObject);
    
    /**
     * 删除存储对象（物理删除，需要检查引用计数）
     * 
     * @param storageObjectId 存储对象ID
     * @return 是否删除成功
     */
    boolean deleteStorageObject(String storageObjectId);
    
    // ==================== 引用计数管理 ====================
    
    /**
     * 增加引用计数
     * 
     * @param storageObjectId 存储对象ID
     * @param increment 增加数量（默认1）
     * @return 更新后的引用计数
     */
    int incrementReferenceCount(String storageObjectId, Integer increment);
    
    /**
     * 减少引用计数
     * 
     * @param storageObjectId 存储对象ID
     * @param decrement 减少数量（默认1）
     * @return 更新后的引用计数
     */
    int decrementReferenceCount(String storageObjectId, Integer decrement);
    
    /**
     * 获取引用计数
     * 
     * @param storageObjectId 存储对象ID
     * @return 引用计数
     */
    int getReferenceCount(String storageObjectId);
    
    // ==================== 存储对象查询 ====================
    
    /**
     * 分页查询存储对象
     * 
     * @param current 当前页
     * @param size 每页大小
     * @param storageType 存储类型（可选）
     * @param storageConfig 存储配置（可选）
     * @param status 状态（可选）
     * @return 分页结果
     */
    IPage<StorageObjectVO> listStorageObjects(long current, long size, String storageType, 
                                             String storageConfig, Integer status);
    
    /**
     * 根据存储类型查询存储对象
     * 
     * @param storageType 存储类型
     * @param current 当前页
     * @param size 每页大小
     * @return 分页结果
     */
    IPage<StorageObjectVO> listByStorageType(String storageType, long current, long size);
    
    /**
     * 查询可清理的存储对象（引用计数为0）
     * 
     * @param limit 限制数量
     * @return 存储对象列表
     */
    List<StorageObject> listCleanableObjects(Integer limit);
    
    // ==================== 存储统计 ====================
    
    /**
     * 按存储类型统计存储对象数量
     * 
     * @param storageType 存储类型
     * @return 存储对象数量
     */
    Long countByStorageType(String storageType);
    
    /**
     * 按存储类型统计存储大小
     * 
     * @param storageType 存储类型
     * @return 存储总大小（字节）
     */
    Long sumSizeByStorageType(String storageType);
    
    /**
     * 统计重复文件节省的空间
     * 
     * @return 节省的空间（字节）
     */
    Long calculateSpaceSaved();
    
    /**
     * 获取存储统计信息
     * 
     * @return 统计信息Map
     */
    Map<String, Object> getStorageStats();
    
    // ==================== 存储维护 ====================
    
    /**
     * 验证存储对象完整性
     * 
     * @param storageObjectId 存储对象ID
     * @return 验证结果
     */
    boolean verifyStorageObjectIntegrity(String storageObjectId);
    
    /**
     * 批量验证存储对象完整性
     * 
     * @param storageObjectIds 存储对象ID列表
     * @return 验证结果Map（ID -> 验证结果）
     */
    Map<String, Boolean> batchVerifyIntegrity(List<String> storageObjectIds);
    
    /**
     * 查询需要验证的存储对象
     * 
     * @param lastVerifyBefore 最后验证时间之前
     * @param limit 限制数量
     * @return 存储对象列表
     */
    List<StorageObject> listObjectsNeedVerify(LocalDateTime lastVerifyBefore, Integer limit);
    
    /**
     * 更新验证状态
     * 
     * @param storageObjectId 存储对象ID
     * @param verifyStatus 验证状态
     * @return 是否更新成功
     */
    boolean updateVerifyStatus(String storageObjectId, Integer verifyStatus);
    
    /**
     * 清理无引用的存储对象
     * 
     * @param batchSize 批次大小
     * @return 清理的数量
     */
    int cleanupUnreferencedObjects(int batchSize);
    
    /**
     * 修复引用计数（重新计算）
     * 
     * @param storageObjectId 存储对象ID
     * @return 修复后的引用计数
     */
    int repairReferenceCount(String storageObjectId);
    
    /**
     * 批量更新存储对象状态
     * 
     * @param storageObjectIds 存储对象ID列表
     * @param status 新状态
     * @return 更新的数量
     */
    int batchUpdateStatus(List<String> storageObjectIds, Integer status);
    
    // ==================== 高级功能 ====================
    
    /**
     * 迁移存储对象到新的存储后端
     * 
     * @param storageObjectId 存储对象ID
     * @param targetStorageType 目标存储类型
     * @param targetBucket 目标存储桶
     * @return 是否迁移成功
     */
    boolean migrateStorageObject(String storageObjectId, String targetStorageType, String targetBucket);
    
    /**
     * 复制存储对象
     * 
     * @param sourceStorageObjectId 源存储对象ID
     * @param targetStorageType 目标存储类型
     * @param targetBucket 目标存储桶
     * @return 新的存储对象
     */
    StorageObject copyStorageObject(String sourceStorageObjectId, String targetStorageType, String targetBucket);
    
    /**
     * 计算存储对象的实际使用情况
     * 
     * @param storageObjectId 存储对象ID
     * @return 使用情况信息
     */
    Map<String, Object> calculateUsageInfo(String storageObjectId);
}
